<script setup>
	import { onLoad } from '@dcloudio/uni-app'
	import { ref, nextTick } from 'vue'
	import { parseTime } from '@/utils/common'
	import aiRequest from '@/utils/aiRequest'
	
	const customBar = getApp().globalData.customBar
	const config = getApp().globalData.config
	const loadingId = ref('')
	const searchValue = ref('')
	const list = ref([])
	let deepseekTask = null
	const page = uni.createSelectorQuery().selectViewport()
	
	function search() {
		if(loadingId.value) {
			uni.showToast({icon: 'none', title: '请等待上一个回答完成'})
		} else if(!searchValue.value) {
			uni.showToast({icon: 'none', title: '请输入你的问题'})
		} else {
			deepseek()
		}
	}
	function deepseek() {
		let userItem = {
			id: uni.$uv.guid(20),
			role: 'user',
			content: searchValue.value,
			createTime: parseTime(new Date(), '{hh}:{ii}'),
		}
		let aiItem = {
			id: uni.$uv.guid(20),
			role: 'assistant',
			content: '',
			createTime: parseTime(new Date(), '{hh}:{ii}'),
			think: '',
			chatId: userItem.id,
		}
		list.value.push(userItem, aiItem)
		searchValue.value = ''
		let messages = []
		list.value.forEach(item => {
			if(item.content) {
				messages.push({
					role: item.role,
					content: item.content
				})
			}
		})
		loadingId.value = aiItem.id
		deepseekTask = aiRequest(messages, deepseekProgress, deepseekComplete, deepseekError)
	}
	function deepseekProgress(think, content) {
		chatContentChange(loadingId.value, think, content)
	}
	function deepseekComplete(think, content) {
		chatContentChange(loadingId.value, think, content)
		deepseekTask = null
		loadingId.value = ''
	}
	function deepseekError(err) {
		console.error(err)
		chatContentChange(loadingId.value, `${err.msg}`)
		loadingId.value = ''
	}
	function chatContentChange(id, think, content) {
		if(id) {
			let chatContent = list.value.find(item => item.id === id)
			if(chatContent) {
				if(think) chatContent.think = think
				chatContent.content = content
				uni.$uv.throttle(dealScroll, 1000)
			}
		}
	}
	function pauseChat() {
		if(deepseekTask) {
			deepseekTask.stop()
			deepseekTask = null
			loadingId.value = ''
		}
	}
	function deleteChat(id) {
		let index = list.value.findIndex(item => item.id === id)
		if(index != -1) list.value.splice(index, 1)
	}
	function queryScrollHeight() {
		return new Promise(resolve => {
			uni.createSelectorQuery().selectViewport().fields({
				size: true,
				scrollOffset: true,
				properties: ['scrollHeight',]
			}, res => {
				resolve(res)
			}).exec()
		})
    }
	function dealScroll() {
		nextTick(() => {
			queryScrollHeight().then(res => {
				let autoScroll = res.scrollTop + res.height >= res.scrollHeight - 80
				if(autoScroll) {
					uni.pageScrollTo({
						scrollTop: res.scrollHeight - res.height
					})
				}
			})
		})
	}
	
	onLoad(() => {
		
	})
</script>

<template>
	<view class="app-container" :style="{paddingTop: customBar + 'px'}">
		<navbar text="AI 智能助手"></navbar>
		<view class="app-content">
			<view class="chat-list" v-if="list.length">
				<template v-for="item in list" :key="item.id">
					<view class="chat-box left" v-if="item.role == 'assistant'">
						<uv-avatar text="AI" bg-color="#2979ff" size="56" font-size="28"></uv-avatar>
						<view class="chat-info">
							<view class="info-box">
								<view class="info-think"><ua-markdown :source="item.think" /></view>
								<view><ua-markdown :source="item.content" /></view>
							</view>
							<view class="info-bottom">
								<text class="bottom-time">{{item.createTime}}</text>
								<view class="bottom-info">
									<template v-if="loadingId === item.id">
										<view class="bottom-box">
											<uv-loading-icon size="24" color="rgba(96, 165, 250, 0.7)"></uv-loading-icon>
											<text>生成中</text>
										</view>
										<view class="bottom-box" @click="pauseChat">
											<uv-icon name="pause-circle-fill" color="rgba(96, 165, 250, 0.7)" size="30"></uv-icon>
											<text>暂停</text>
										</view>
									</template>
									<view class="bottom-box" v-else @click="deleteChat(item.id)">
										<uv-icon name="trash-fill" color="rgba(96, 165, 250, 0.7)" size="30"></uv-icon>
										<text>删除</text>
									</view>
								</view>
							</view>
						</view>
					</view>
					<view class="chat-box right" v-else>
						<uv-avatar :src="config.appInfo.logo" size="56"></uv-avatar>
						<view class="chat-info">
							<view class="info-box">{{item.content}}</view>
							<view class="info-bottom">
								<view class="bottom-info">
									<view class="bottom-box" @click="deleteChat(item.id)">
										<uv-icon name="trash-fill" color="rgba(96, 165, 250, 0.7)" size="30"></uv-icon>
										<text>删除</text>
									</view>
								</view>
								<text class="bottom-time">{{item.createTime}}</text>
							</view>
						</view>
					</view>
				</template>
			</view>
			<view class="empty-box" v-else>
				<empty text="还没有提问题哟..." ></empty>
			</view>
		</view>
		<view class="app-bottom">
			<view class="search-box">
				<uv-input v-model="searchValue" placeholder="输入你的问题..." placeholderStyle="color: rgba(147, 197, 253, 0.5)" color="#DBEAFE" border="none"
					clearable confirmType="search" @confirm="search"></uv-input>
			</view>
			<view class="search-btn" @click="search">
				<uv-icon name="/static/images/icon/send.png" size="40" />
			</view>
		</view>
	</view>
</template>

<style lang="scss" scoped>
	.app-container{
		padding-bottom: 132rpx;
		.app-content{
			padding: 24rpx 12rpx;
			.chat-list{
				display: flex;
				flex-direction: column;
				gap: 24rpx;
				.chat-box{
					display: flex;
					gap: 12rpx;
					&.left{
						flex-direction: row;
						.info-box{
							border-radius: 0 20rpx 20rpx 20rpx;
							.info-box{
								text-align: left;
							}
						}
					}
					&.right{
						flex-direction: row-reverse;
						.info-box{
							border-radius: 20rpx 0 20rpx 20rpx;
							.info-box{
								text-align: right;
							}
						}
					}
				}
				.chat-info{
					min-width: 40%;
					max-width: 84%;
					.info-box{
						padding: 12rpx;
						background-color: rgba(30, 64, 175, 0.4);
						border: 2px solid rgba(59, 130, 246, 0.3);
						color: #BFDBFE;
						.info-think{
							padding: 0 12rpx 24rpx;
							color: rgba(96, 165, 250, 0.7);
							font-size: var(--theme-sm);
							line-height: var(--theme-sm-line);
						}
					}
					.info-bottom{
						margin-top: 6rpx;
						display: flex;
						justify-content: space-between;
						align-items: center;
						color: #9CA3AF;
						font-size: var(--theme-sm);
						line-height: var(--theme-sm-line);
						.bottom-info{
							display: flex;
							gap: 24rpx;
						}
						.bottom-box{
							padding: 6rpx 12rpx;
							background-color: rgba(30, 64, 175, 0.4);
							display: flex;
							align-items: center;
							gap: 6rpx;
							border-radius: 20rpx;
						}
					}
				}
			}
			.empty-box{
				padding: 48rpx;
				border-radius: 24rpx;
			}
		}
		.app-bottom{
			position: fixed;
			left: 0;
			right: 0;
			bottom: var(--window-bottom);
			z-index: 99;
			height: 132rpx;
			background-color: #16254e;
			padding: 24rpx;
			display: flex;
			align-items: center;
			gap: 24rpx;
			border-top: 2rpx solid rgba(59, 130, 246, 0.2);
			border-bottom: 2rpx solid rgba(59, 130, 246, 0.2);
			.search-box{
				width: calc(100% - 100rpx);
				height: 100%;
				padding-left: 14rpx;
				display: flex;
				flex-direction: column;
				justify-content: center;
				background: rgba(30, 64, 175, 0.3);
				border: 2rpx solid rgba(59, 130, 246, 0.3);
				border-radius: 80rpx;
			}
			.search-btn{
				width: 76rpx;
				height: 76rpx;
				display: flex;
				justify-content: center;
				align-items: center;
				background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);
				border: 2rpx solid rgba(96, 165, 250, 0.3);
				border-radius: 76rpx;
				animation-name: scaleAn;
				animation-duration: 2s;
				animation-iteration-count: infinite;
				animation-direction: alternate;
			}
		}
		
		@keyframes scaleAn {
			from {
				scale: 0.9}
			to {
				scale: 1.1
			}
		}
	}
</style>